package ca.uwindsor.cs.deepweb.utility;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Set;
import java.util.TreeSet;

/**
 * @author Liang Jie
 * 
 */
public class FileSizeDistributionAnalyzer {

	protected ArrayList<Integer> distribution;

	protected int interval;

	protected String directory;

	protected Set<String> extensions;
	
	protected boolean logflag;

	protected ArrayList<Long> sizelist;
	/**
	 * @param size
	 * @param dir
	 * 
	 */
	public FileSizeDistributionAnalyzer(int interval, String dir) {
		extensions = new TreeSet<String>();
		distribution = new ArrayList<Integer>();
		this.interval = interval;
		directory = dir;
		sizelist=new ArrayList<Long>();
	}
	
	public void getLogarithmBasedToInterval(){
		Collections.sort(sizelist);
	}

	public void addExtension(String extension) {
		extensions.add(extension);
	}

	public void go() throws IOException {
		File dir = new File(directory);
		if (dir.isDirectory()) {
			calculate(dir);
		} else {
			calculate(directory);
		}
	}

	public void addSize(long size) {
		sizelist.add(size);
		int offset = new Long(size / interval).intValue();
		if (distribution.size() <= offset) {
			distribution.ensureCapacity(offset);
			for (int i = distribution.size(); i <= offset; i++) {
				distribution.add(i, 0);
			}
		}
		Integer quantity = distribution.get(offset);
		quantity++;
		distribution.set(offset, quantity);
	}
	
	protected void calculate(File dir) {
		File[] dataFiles = dir.listFiles();
		for (int i = 0; i < dataFiles.length; i++) {
			File file = dataFiles[i];
			if (file.isFile()) {
				String extension;
				int j = file.getName().lastIndexOf('.');
				extension = file.getName().substring(j + 1);
				if (extensions.contains(extension)) {
					Long size = new Long(file.length());
					addSize(size.intValue());
				}
			} else if (file.isDirectory()) {
				calculate(file);
			}
		}
	}

	protected void calculate(String file) throws IOException {
		BufferedReader reader = new BufferedReader(new InputStreamReader(
				new FileInputStream(file)));
		String line = reader.readLine();
		StringBuilder data = new StringBuilder();
		while (line != null) {
			data.append(line + " ");
			line = reader.readLine();
		}
		String temp = data.toString();
		String[] temp2 = temp.split("\\s");
		for (String s : temp2) {
			addSize(Long.parseLong(s));
		}
		reader.close();
	}

	public ArrayList<Integer> getDistribution() {
		return distribution;
	}

	/**
	 * @param directory
	 *            the directory to set
	 */
	public void setDirectory(String directory) {
		this.directory = directory;
	}

	/**
	 * @return the interval
	 */
	public int getInterval() {
		return interval;
	}

	/**
	 * @param interval
	 *            the interval to set
	 */
	public void setInterval(int interval) {
		this.interval = interval;
	}

	/**
	 * @return the directory
	 */
	public String getDirectory() {
		return directory;
	}

	/**
	 * Check whether a files is required to be indexed using the given
	 * extension(s)
	 * 
	 * @param filename
	 * @return
	 */
	protected boolean isValidExtension(String filename) {
		String extension;
		int j = filename.lastIndexOf('.');
		extension = filename.substring(j + 1);
		if (extensions.contains(extension)) {
			return true;
		} else {
			return false;
		}
	}

	public static void main(String[] args) {

		// args = new String[3];
		// args[0] = Integer.toString(1024);
		// args[1] = "E:/Java/NetBeans_Projects/Loader";
		// args[2] = "xml";
//		int size = Integer.parseInt(args[0]);
//		String[] extensions = args[2].split(",");
//
//		FileSizeDistributionAnalyzer analyzer = new FileSizeDistributionAnalyzer(
//				size, args[1]);
//		for (int index = 0; index < extensions.length; index++) {
//			analyzer.addExtension(extensions[index]);
//		}
//		System.out.println("Start!");
//		try {
//			analyzer.go();
//		} catch (IOException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//		ArrayList<Integer> distribution = analyzer.getDistribution();
//		StringBuffer result = new StringBuffer();
//		for (Integer value : distribution) {
//			System.out.println(value);
//		}
//		for (int i = 1; i < distribution.size(); i++) {
//			distribution.set(i, new Integer(distribution.get(i)
//					+ distribution.get(i - 1)));
//			result.append("less than or equals to " + (i + 1) + "k letter");
//			result.append("\t");
//			result.append(distribution.get(i));
//			result.append("\n");
//		}
//
//		System.out.println(result);
		
		FileSizeDistributionAnalyzer analyzer = new FileSizeDistributionAnalyzer(1,args[0]);
		try {
			analyzer.go();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		ArrayList<Integer> distribution = analyzer.getDistribution();
		StringBuilder builder = new StringBuilder();
		for (Integer value : distribution) {
			builder.append(value);
			builder.append(" ");
		}
		FileOutputStream fp;
		try {
			fp = new FileOutputStream(args[1]);
			fp.write(builder.toString().getBytes());
			fp.flush();
			fp.close();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
